home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
os2
/
octa209s.zip
/
octave-2.09
/
src
/
sysdep.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-10
|
14KB
|
736 lines
/*
Copyright (C) 1996 John W. Eaton
This file is part of Octave.
Octave is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
Octave is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
The function gethostname was adapted from a similar function from GNU
Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free
Software Foundation, Inc.
*/
/* Modified by Klaus Gebhardt, 1996 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <cfloat>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream.h>
#ifdef HAVE_UNISTD_H
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <unistd.h>
#endif
#if defined (HAVE_TERMIOS_H)
#include <termios.h>
#elif defined (HAVE_TERMIO_H)
#include <termio.h>
#elif defined (HAVE_SGTTY_H)
#include <sgtty.h>
#else
LOSE! LOSE!
#endif
#ifdef __EMX__
#include <float.h>
#include <sys/uflags.h>
#endif
#if defined (HAVE_FLOATINGPOINT_H)
#include <floatingpoint.h>
#endif
#if defined (HAVE_IEEEFP_H)
#include <ieeefp.h>
#endif
#if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
#include <sys/utsname.h>
#endif
#ifndef __EMX__
#if defined (USE_READLINE)
#include <readline/readline.h>
#include <readline/tilde.h>
#endif
extern char *term_clrpag;
extern "C" void _rl_output_character_function ();
#else
#include <readline/readline.h>
#include <readline/tilde.h>
#include <sys/ioctl.h>
extern "C"
{
extern void tputs ();
extern char *term_clrpag;
extern void _rl_output_character_function ();
}
#endif
#include "mach-info.h"
#include "oct-math.h"
#include "defun.h"
#include "error.h"
#include "help.h"
#include "input.h"
#include "mappers.h"
#include "oct-obj.h"
#include "pager.h"
#include "pathlen.h"
#include "ov.h"
#include "sysdep.h"
#include "toplev.h"
#include "utils.h"
#ifndef STDIN_FILENO
#define STDIN_FILENO 1
#endif
#if defined (__386BSD__) || defined (__FreeBSD__)
static void
BSD_init (void)
{
#if defined (HAVE_FLOATINGPOINT_H)
// Disable trapping on common exceptions.
fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
#endif
}
#endif
#if defined (NeXT)
extern "C"
{
typedef void (*_cplus_fcn_int) (int);
extern void (*malloc_error (_cplus_fcn_int)) (int);
}
static void
malloc_handler (int code)
{
if (code == 5)
warning ("hopefully recoverable malloc error: freeing wild pointer");
else
{
panic ("probably irrecoverable malloc error: code %d", code);
}
}
static void
NeXT_init (void)
{
malloc_error (malloc_handler);
}
#endif
#if defined (__EMX__)
OS2_init (void)
{
_control87 ((EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW
| EM_UNDERFLOW | EM_INEXACT), MCW_EM);
_uflags (_UF_SBRK_MODEL, _UF_SBRK_ARBITRARY);
}
#endif
#if defined (SCO)
static void
SCO_init (void)
{
#if defined (HAVE_IEEEFP_H)
// Disable trapping on common exceptions.
fpsetmask (~(FP_X_OFL|FP_X_INV|FP_X_DZ|FP_X_DNML|FP_X_UFL|FP_X_IMP));
#endif
}
#endif
void
sysdep_init (void)
{
#if defined (__386BSD__) || defined (__FreeBSD__)
BSD_init ();
#elif defined (NeXT)
NeXT_init ();
#elif defined (__EMX__)
OS2_init ();
#elif defined (SCO)
SCO_init ();
#endif
octave_ieee_init ();
}
// Set terminal in raw mode. From less-177.
//
// Change terminal to "raw mode", or restore to "normal" mode.
// "Raw mode" means
// 1. An outstanding read will complete on receipt of a single keystroke.
// 2. Input is not echoed.
// 3. On output, \n is mapped to \r\n.
// 4. \t is NOT expanded into spaces.
// 5. Signal-causing characters such as ctrl-C (interrupt),
// etc. are NOT disabled.
// It doesn't matter whether an input \n is mapped to \r, or vice versa.
void
raw_mode (int on)
{
static int curr_on = 0;
int tty_fd = STDIN_FILENO;
if (! isatty (tty_fd))
{
if (interactive)
error ("stdin is not a tty!");
return;
}
if (on == curr_on)
return;
#if defined (HAVE_TERMIOS_H)
{
struct termios s;
static struct termios save_term;
if (on)
{
// Get terminal modes.
tcgetattr (tty_fd, &s);
// Save modes and set certain variables dependent on modes.
save_term = s;
// ospeed = s.c_cflag & CBAUD;
// erase_char = s.c_cc[VERASE];
// kill_char = s.c_cc[VKILL];
// Set the modes to the way we want them.
s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
s.c_oflag |= (OPOST|ONLCR);
#if defined (OCRNL)
s.c_oflag &= ~(OCRNL);
#endif
#if defined (ONOCR)
s.c_oflag &= ~(ONOCR);
#endif
#if defined (ONLRET)
s.c_oflag &= ~(ONLRET);
#endif
s.c_cc[VMIN] = 1;
s.c_cc[VTIME] = 0;
}
else
{
// Restore saved modes.
s = save_term;
}
tcsetattr (tty_fd, TCSAFLUSH, &s);
}
#elif defined (HAVE_TERMIO_H)
{
struct termio s;
static struct termio save_term;
if (on)
{
// Get terminal modes.
ioctl (tty_fd, TCGETA, &s);
// Save modes and set certain variables dependent on modes.
save_term = s;
// ospeed = s.c_cflag & CBAUD;
// erase_char = s.c_cc[VERASE];
// kill_char = s.c_cc[VKILL];
// Set the modes to the way we want them.
s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
s.c_oflag |= (OPOST|ONLCR);
#if defined (OCRNL)
s.c_oflag &= ~(OCRNL);
#endif
#if defined (ONOCR)
s.c_oflag &= ~(ONOCR);
#endif
#if defined (ONLRET)
s.c_oflag &= ~(ONLRET);
#endif
s.c_cc[VMIN] = 1;
s.c_cc[VTIME] = 0;
}
else
{
// Restore saved modes.
s = save_term;
}
ioctl (tty_fd, TCSETAW, &s);
}
#elif defined (HAVE_SGTTY_H)
{
struct sgttyb s;
static struct sgttyb save_term;
if (on)
{
// Get terminal modes.
ioctl (tty_fd, TIOCGETP, &s);
// Save modes and set certain variables dependent on modes.
save_term = s;
// ospeed = s.sg_ospeed;
// erase_char = s.sg_erase;
// kill_char = s.sg_kill;
// Set the modes to the way we want them.
s.sg_flags |= CBREAK;
s.sg_flags &= ~(ECHO);
}
else
{
// Restore saved modes.
s = save_term;
}
ioctl (tty_fd, TIOCSETN, &s);
}
#else
LOSE! LOSE!
#endif
curr_on = on;
}
// Read one character from the terminal.
int
kbhit (void)
{
int c;
flush_octave_stdout ();
raw_mode (1);
c = cin.get ();
raw_mode (0);
return c;
}
string
octave_getcwd (void)
{
string retval;
char buf[MAXPATHLEN];
char *tmp = 0;
#if defined (__EMX__)
tmp = _getcwd2 (buf, MAXPATHLEN);
#elif defined (HAVE_GETWD)
tmp = getwd (buf);
#elif defined (HAVE_GETCWD)
tmp = getwd (buf, MAXPATHLEN);
#endif
if (tmp)
retval = tmp;
else
error ("unable to find current directory");
return retval;
}
int
octave_chdir (const string& path)
{
#if defined (__EMX__)
int retval = -1;
char *tmp_path = strsave (path.c_str ());
if (path.length () == 2 && path[1] == ':')
{
char *upper_case_dir_name = strupr (tmp_path);
_chdrive (upper_case_dir_name[0]);
if (_getdrive () == upper_case_dir_name[0])
retval = _chdir2 ("/");
}
else
retval = _chdir2 (tmp_path);
delete [] tmp_path;
return retval;
#else
return chdir (path.c_str ());
#endif
}
DEFUN (clc, , ,
"clc (): clear screen")
{
octave_value_list retval;
rl_beg_of_line ();
rl_kill_line (1);
#if ! defined (_GO32_)
if (term_clrpag)
tputs (term_clrpag, 1, _rl_output_character_function);
else
crlf ();
#else
crlf ();
#endif
fflush (rl_outstream);
return retval;
}
DEFALIAS (home, clc);
DEFUN (getenv, args, ,
"getenv (STRING): get environment variable values")
{
octave_value_list retval;
int nargin = args.length ();
if (nargin == 1)
{
string tstr = args(0).string_value ();
const char *name = tstr.c_str ();
if (! error_state)
{
char *value = getenv (name);
if (value)
retval = value;
else
retval = "";
}
}
else
print_usage ("getenv");
return retval;
}
DEFUN (putenv, args, ,
"putenv (VAR, VALUE): define environment variable VAR=VALUE")
{
octave_value_list retval;
int nargin = args.length ();
if (nargin == 2)
{
string var = args(0).string_value ();
if (! error_state)
{
string val = args(1).string_value ();
if (! error_state)
oct_putenv (var.c_str (), val.c_str ());
else
error ("putenv: second argument should be a string");
}
else
error ("putenv: first argument should be a string");
}
else
print_usage ("putenv");
return retval;
}
DEFUN (kbhit, , ,
"kbhit: get a single character from the terminal")
{
octave_value_list retval;
// XXX FIXME XXX -- add timeout and default value args?
if (interactive || really_forced_interactive)
{
int c = kbhit ();
char *s = new char [2];
s[0] = c;
s[1] = '\0';
retval = s;
}
return retval;
}
DEFUN (pause, args, ,
"pause (seconds): suspend program execution")
{
octave_value_list retval;
int nargin = args.length ();
if (! (nargin == 0 || nargin == 1))
{
print_usage ("pause");
return retval;
}
if (nargin == 1)
{
double dval = args(0).double_value ();
if (! error_state)
{
if (xisnan (dval))
warning ("pause: NaN is an invalid delay");
else if (xisinf (dval))
kbhit ();
else
{
int delay = NINT (dval);
if (delay > 0)
sleep (delay);
}
}
}
else
kbhit ();
return retval;
}
DEFUN (sleep, args, ,
"sleep (seconds): suspend program execution")
{
octave_value_list retval;
if (args.length () == 1)
{
double dval = args(0).double_value ();
if (! error_state)
{
if (xisnan (dval))
warning ("sleep: NaN is an invalid delay");
else
{
int delay = NINT (dval);
if (delay > 0)
sleep (delay);
}
}
}
else
print_usage ("sleep");
return retval;
}
DEFUN (usleep, args, ,
"usleep (microseconds): suspend program execution")
{
octave_value_list retval;
if (args.length () == 1)
{
double dval = args(0).double_value ();
if (! error_state)
{
if (xisnan (dval))
warning ("usleep: NaN is an invalid delay");
else
{
#if defined (HAVE_USLEEP)
int delay = NINT (dval);
if (delay > 0)
usleep (delay);
#elif defined (HAVE__SLEEP2)
int delay = NINT (dval / 1e3);
if (delay > 0)
_sleep2 (delay);
#else
int delay = NINT (dval / 1e6);
if (delay > 0)
sleep (delay);
#endif
}
}
}
else
print_usage ("usleep");
return retval;
}
// XXX FIXME XXX -- maybe this should only return 1 if IEEE floating
// point functions really work.
DEFUN (isieee, , ,
"isieee (): return 1 if host uses IEEE floating point")
{
oct_mach_info::float_format flt_fmt =
oct_mach_info::native_float_format ();
return (double) (flt_fmt == oct_mach_info::ieee_little_endian
|| flt_fmt == oct_mach_info::ieee_big_endian);
}
#if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
int
gethostname (char *name, int namelen)
{
int i;
struct utsname ut;
--namelen;
uname (&ut);
i = strlen (ut.nodename) + 1;
strncpy (name, ut.nodename, i < namelen ? i : namelen);
name[namelen] = '\0';
return 0;
}
#endif
// The check for error state allows us to do this:
//
// string foo = oct_tilde_expand (args(0).string_value ());
//
// without having to use a temporary and check error_state before
// calling oct_tilde_expand.
string
oct_tilde_expand (const string& name)
{
string retval;
if (! error_state)
{
char *tmp = tilde_expand (name.c_str ());
retval = tmp;
delete [] tmp;
}
return retval;
}
// A vector version of the above.
string_vector
oct_tilde_expand (const string_vector& names)
{
string_vector retval;
if (! error_state)
{
int n = names.length ();
retval.resize (n);
for (int i = 0; i < n; i++)
retval[i] = oct_tilde_expand (names[i]);
}
return retval;
}
DEFUN (tilde_expand, args, ,
"tilde_expand (STRING): perform tilde expansion on STRING")
{
octave_value_list retval;
int nargin = args.length ();
if (nargin == 1)
retval = oct_tilde_expand (args(0).all_strings ());
else
print_usage ("tilde_expand");
return retval;
}
#if defined (__EMX__) && defined (OS2)
DEFUN_TEXT (extproc, , ,
"extproc : ignored by Octave")
{
return octave_value_list ();
}
DEFALIAS (EXTPROC, extproc);
DEFUN (add_to_command_number, args, ,
"add_to_command_number: add argument to the current command number")
{
octave_value_list retval;
int nargin;
if ((nargin = args.length ()) != 1)
{
print_usage ("add_to_command_number");
return retval;
}
double tmp_d = args(0).double_value ();
if (error_state || ((int) tmp_d != tmp_d))
error ("add_to_command_number: expecting integer as argument");
else
current_command_number += (int) tmp_d;
return retval;
}
#endif
/*
;;; Local Variables: ***
;;; mode: C++ ***
;;; End: ***
*/